<?php

defined('BASEPATH') or die('No direct script access allowed');

/**
 * 记账控制器
 * @author  Karson
 * @name    bill.php
 * @since   2013-2-27 22:40:43
 */
class Bill_Controller extends Controller {

    function _init() {
        check_level();
        $user_id = isset($_GET['user_id']) ? $this->input->get("user_id") : $this->auth->user_id;
        $this->user_id = (int) $user_id;
        $this->category->load_user_category($user_id);
        $this->account->load_user_account($user_id);
    }

    function index($type = 'expense', $page = 1, $pagesize = 10) {
        $this->view->assign("familyinfo", $this->family->get_family());
        $this->_set_bill_data($type, $page, $pagesize);
        render("mobile/bill/index", array('user_id' => $this->user_id));
    }

    function _set_bill_data($type = 'expense', $page = 1, $pagesize = 10) {
        $where = array();
        $where[] = $type ? "type IN ('expense', 'income')" : '1=1';
        $memo = '';
        if (isset($_GET['user_id']) && $this->user_id != $this->auth->user_id) {
            $userinfo = $this->auth->get_user_data($this->user_id);
            $this->view->assign("bill_title", "{$userinfo['nickname']}的账单");
            $familyids = $this->family->get_family_ids();
            $where[] = "family='1' AND user_id ='{$this->user_id}'";
        } else {
            $this->view->assign("bill_title", "我的账单");
            $where[] = "user_id = '{$this->auth->user_id}'";
        }
        if (isset($_GET['memo'])) {
            $memo = $this->input->get("memo");
            if ($memo != '')
                $where[] = "memo LIKE '%{$memo}%'";
        }
        if (isset($_GET['category_id'])) {
            $category_id = $this->input->get("category_id");
            //如果不是数组
            if ($category_id && !is_array($category_id)) {
                $categoryinfo = get_category($category_id);
                if ($categoryinfo) {
                    $sonlist = array_keys(get_category_list($type, $category_id));
                    $category_id = $sonlist ? $sonlist : array($category_id);
                } else {
                    $category_id = array($category_id);
                }
            }
            foreach ($category_id as $k => & $v) {
                $v = (int) $v;
            }
            if ($category_id && !in_array(0, $category_id)) {
                $where[] = "category_id IN (" . implode(",", $category_id) . ")";
            }
        }
        if (isset($_GET['account_id'])) {
            $account_id = $this->input->get("account_id");
            $account_id = !is_array($account_id) ? array($account_id) : $account_id;
            if ($account_id && !in_array(0, $account_id)) {
                foreach ($account_id as $k => & $v) {
                    $v = (int) $v;
                }
                $where[] = "account_id IN (" . implode(",", $account_id) . ")";
            }
        }
        if (isset($_GET['inaccount_id'])) {
            $inaccount_id = $this->input->get("inaccount_id");
            $inaccount_id = !is_array($inaccount_id) ? array($inaccount_id) : $inaccount_id;
            if (!in_array(0, $inaccount_id)) {
                foreach ($inaccount_id as $k => & $v) {
                    $v = (int) $v;
                }
                $where[] = "inaccount_id IN (" . implode(",", $inaccount_id) . ")";
            }
        }
        $orderbyresult = 'id DESC';
        $orderby = $this->input->get("orderby");
        if ($orderby) {
            $orderenum = array(0 => 'occurtime', 1 => 'amount');
            $orderarr = explode(",", $orderby);
            if (count($orderarr) == 2) {
                if ($orderarr[1] > 0 && $orderarr[1] < 3 && isset($orderenum[$orderarr[0]])) {
                    $orderbyresult = $orderenum[$orderarr[0]] . " " . ($orderarr[1] == 1 ? 'DESC' : 'ASC');
                }
            }
        }
        $limitdate = $this->input->get("limitdate");
        $startdate = $enddate = 0;
        if ($limitdate) {
            switch ($limitdate) {
                case 1:
                    $startdate = get_unixtime();
                    $enddate = get_unixtime('day', 0, 'end');
                    break;
                case 2:
                    $startdate = get_unixtime('day', -1);
                    $enddate = get_unixtime('day', -1, 'end');
                    break;
                case 3:
                    $startdate = get_unixtime('week');
                    $enddate = get_unixtime('week', 0, 'end');
                    break;
                case 4:
                    $startdate = get_unixtime('week', -1);
                    $enddate = get_unixtime('week', -1, 'end');
                    break;
                case 5:
                    $startdate = get_unixtime('month');
                    $enddate = get_unixtime('month', 0, 'end');
                    break;
                case 6:
                    $startdate = get_unixtime('month', -1);
                    $enddate = get_unixtime('month', -1, 'end');
                    break;
                case 7:
                    $startdate = get_unixtime('year');
                    $enddate = get_unixtime('year', 0, 'end');
                    break;
                case 8:
                    $startdate = get_unixtime('year', -1);
                    $enddate = get_unixtime('year', -1, 'end');
                    break;
                default:
                    break;
            }
            if (($enddate % 86400) == 0) {
                $enddate += 86399;
            }
        } else {
            $startdate = $this->input->get("startdate");
            $enddate = $this->input->get("enddate");
            $startdate = $startdate ? strtotime($startdate) : 0;
            $enddate = $enddate ? strtotime($enddate) + 86399 : 0;
        }
        if (($startdate || $enddate)) {
            if (!$startdate) {
                $where[] = "(`occurtime` <={$enddate})";
            } else if (!$enddate) {
                $where[] = "(`occurtime` >= {$startdate})";
            } else if ($startdate <= $enddate) {
                $where[] = "(`occurtime` >= {$startdate} AND `occurtime`<={$enddate})";
            }
        }
        $startamount = $endamount = 0;
        $limitamount = $this->input->get("limitamount");
        if ($limitamount) {
            switch ($limitamount) {
                case 1:
                    $endamount = 10;
                    break;
                case 2:
                    $startamount = 11;
                    $endamount = 100;
                    break;
                case 3:
                    $startamount = 101;
                    $endamount = 1000;
                    break;
                case 4:
                    $startamount = 1001;
                    $endamount = 10000;
                    break;
                case 5:
                    $startamount = 10001;
                    break;
                default:
                    break;
            }
        } else {
            $startamount = $this->input->get("startamount");
            $endamount = $this->input->get("endamount");
        }
        if ($startamount || $endamount) {
            if (!$startamount) {
                $where[] = "(`amount` <={$endamount})";
            } else if (!$endamount) {
                $where[] = "(`amount` >= {$startamount})";
            } else if ($startamount <= $endamount) {
                $where[] = "(`amount` >= {$startamount} AND `amount`<={$endamount})";
            }
        }

        $startoutstanding = $endoutstanding = 0;
        $limitoutstanding = $this->input->get("limitoutstanding");
        if ($limitoutstanding) {
            switch ($limitoutstanding) {
                case 1:
                    $endoutstanding = 10;
                    break;
                case 2:
                    $startoutstanding = 11;
                    $endoutstanding = 100;
                    break;
                case 3:
                    $startoutstanding = 101;
                    $endoutstanding = 1000;
                    break;
                case 4:
                    $startoutstanding = 1001;
                    $endoutstanding = 10000;
                    break;
                case 5:
                    $startoutstanding = 10001;
                    break;
                default:
                    break;
            }
        } else {
            $startoutstanding = $this->input->get("startoutstanding");
            $endoutstanding = $this->input->get("endoutstanding");
        }
        if ($startoutstanding || $endoutstanding) {
            if (!$startoutstanding) {
                $where[] = "(`outstanding` <={$endoutstanding})";
            } else if (!$endoutstanding) {
                $where[] = "(`outstanding` >= {$startoutstanding})";
            } else if ($startoutstanding <= $endoutstanding) {
                $where[] = "(`outstanding` >= {$startoutstanding} AND `outstanding`<={$endoutstanding})";
            }
        }
        $where = implode(" AND ", $where);
        $result = $this->db->one("SELECT COUNT(*) AS num FROM {pre}bill WHERE {$where}");
        $total = $result['num'];
        $offset = ($page - 1) * $pagesize;
        $pagelist = $this->page->get("/mobile/bill/index/{$type}/{page}/{$pagesize}/", $total, $page, $pagesize, false, false);

        $list = array();
        $this->db->query("SELECT * FROM {pre}bill WHERE {$where} ORDER BY {$orderbyresult} LIMIT {$offset},{$pagesize}", "list");
        while ($row = $this->db->get_array("list")) {
            $row['category'] = get_category($row['category_id']);
            if (isset($row['category']['father_id'])) {
                $row['father_category'] = get_category($row['category']['father_id']);
            } else {
                $row['father_category'] = array('id' => 0, 'name' => '未知');
            }
            $row['account'] = get_account($row['account_id']);
            $row['inaccount'] = get_account($row['inaccount_id']);
            $row['memo'] = cutstr($row['memo'], 40, '...');
            $row['memo'] = $memo ? str_replace($memo, "<font color=red>{$memo}</font>", $row['memo']) : $row['memo'];
            $list[] = $row;
        }
        $data = array("pagelist" => $pagelist, 'list' => $list, 'type' => $type);
        $this->view->assign($data);
    }

    function add($type = 'expense') {
        $type = array_key_exists($type, get_bill_type()) ? $type : 'expense';
        if ($this->form->is_submit()) {
            $data = $this->input->post("row");
            $data['type'] = $type;
            if (!$data['amount']) {
                $info = "金额必须大于等于0";
                $status = "n";
            } else if (($data['type'] == 'transfer' || $data['type'] == 'credit') && ($data['account_id'] == $data['inaccount_id'])) {
                $info = $data['type'] == 'transfer' ? "转出和转入账户不能相同" : "账户和还款信用卡不能相同";
                $status = "n";
            } else {
                $id = $this->_insert($data);
                $info = "提交成功";
                $status = "y";
            }
            dialog_output($status, $info, $data);
        }
        $data['type'] = $type;
        render("mobile/bill/add", $data);
    }

    function edit($id) {
        $show = $this->db->one("SELECT * FROM {pre}bill WHERE id='{$id}'");
        if ($show) {
            if ($show['user_id'] == $this->auth->user_id) {
                if ($this->form->is_submit()) {
                    $data = $this->input->post("row");
                    $value['occurtime'] = strtotime($data['occurtime']);
                    $value['category_id'] = isset($data['category_id']) ? (int) $data['category_id'] : 0;
                    $value['account_id'] = isset($data['account_id']) ? (int) $data['account_id'] : 0;
                    $value['inaccount_id'] = isset($data['inaccount_id']) ? (int) $data['inaccount_id'] : 0;
                    $value['amount'] = (float) $data['amount'];
                    $value['memo'] = $data['memo'];
                    $value['family'] = isset($data['notinfamily']) ? 0 : 1;
                    $data['modifytime'] = time();
                    $id = $this->db->update("{pre}bill", $value, array('id' => $id));
                    if ($id) {
                        if ($show['account_id'] != $value['account_id']) {
                            $amount = $show['type'] == 'income' ? -$show['amount'] : $show['amount'];
                            $this->account->update_user_account($show['account_id'], $amount, "编辑记账[{$value['memo']}],ID[{$id}]");
                            $this->account->update_user_account($value['account_id'], -$amount, "编辑记账[{$value['memo']}],ID[{$id}]");
                        } else {
                            $amount = $show['type'] == 'income' ? $value['amount'] - $show['amount'] : $show['amount'] - $value['amount'];
                            $this->account->update_user_account($value['account_id'], $amount, "编辑记账[{$value['memo']}],ID[{$id}]");
                        }
                        if ($show['type'] == 'credit' || $show['type'] == 'transfer') {
                            if ($show['inaccount_id'] != $value['inaccount_id']) {
                                $this->account->update_user_account($show['inaccount_id'], -$show['amount'], "编辑记账[{$value['memo']}],ID[{$id}]");
                                $this->account->update_user_account($value['inaccount_id'], $value['amount'], "编辑记账[{$value['memo']}],ID[{$id}]");
                            } else {
                                $this->account->update_user_account($value['inaccount_id'], $value['amount'] - $show['amount'], "编辑记账[{$value['memo']}],ID[{$id}]");
                            }
                        }
                    }
                    $status = 'y';
                    $info = '操作成功!';
                    dialog_output($status, $info);
                }
                $this->view->assign("show", $show);
                render("mobile/bill/edit");
            } else {
                render("error", '不能进行越权操作');
            }
        } else {
            render("error", '记录未找到');
        }
    }

    function settle($id) {
        $show = $this->db->one("SELECT * FROM {pre}bill WHERE id='{$id}'");
        if ($show) {
            if ($show['user_id'] == $this->auth->user_id) {
                if ($show['type'] == 'borrow') {
                    if (segment(3) == 'show') {
                        $show['list'] = $this->db->simple("SELECT * FROM {pre}bill WHERE father_id='{$show['id']}' ORDER BY createtime DESC");
                        $this->view->assign("show", $show);
                        render("mobile/bill/settle_show");
                    } else {
                        if ($this->form->is_submit()) {
                            $data = $this->input->post("row");
                            if ($data['amount'] <= $show['outstanding'] && $data['amount'] > 0) {
                                if (strtotime($data['occurtime']) >= $show['occurtime']) {
                                    $this->db->query("UPDATE {pre}bill SET outstanding=outstanding-{$data['amount']} WHERE id='{$show['id']}'");
                                    $value['type'] = $show['type'];
                                    $value['father_id'] = $show['id'];
                                    $value['user_id'] = $show['user_id'];
                                    $value['occurtime'] = strtotime($data['occurtime']);
                                    $value['category_id'] = $show['category_id'] == 1 ? 3 : 4;
                                    $value['account_id'] = isset($data['account_id']) ? (int) $data['account_id'] : 0;
                                    $value['inaccount_id'] = isset($data['inaccount_id']) ? (int) $data['inaccount_id'] : 0;
                                    $value['amount'] = (float) $data['amount'];
                                    $value['memo'] = "[{$show['memo']}][" . ($show['category_id'] == 1 ? "还入" : "还出") . "]" . ($data['memo'] ? "[{$data['memo']}]" : '');
                                    $value['family'] = isset($data['notinfamily']) ? 0 : 1;
                                    $value['createtime'] = time();
                                    $id = $this->db->insert("{pre}bill", $value);
                                    $amount = $show['category_id'] == 1 ? $value['amount'] : -$value['amount'];
                                    $this->account->update_user_account($value['account_id'], $amount, "结算记账{$value['memo']},ID[{$show['id']}],流水ID[{$id}]");
                                    $status = 'y';
                                    $info = '操作成功!';
                                } else {
                                    $status = 'n';
                                    $info = '时间不能小于原始记录的时间';
                                }
                            } else {
                                $status = 'n';
                                $info = '金额不能大于需要结清的金额';
                            }
                            dialog_output($status, $info);
                        }
                        $this->view->assign("show", $show);
                        render("mobile/bill/settle");
                    }
                } else {
                    render("error", '无记录无需进行结清操作');
                }
            } else {
                render("error", '不能进行越权操作');
            }
        } else {
            render("error", '记录未找到');
        }
    }

    function multi() {
        if ($this->form->is_submit()) {
            $row = $this->input->post("row");
            $i = 0;
            foreach ($row as $m => $n) {
                if (isset($n[$n['type']])) {
                    $data = $n[$n['type']];
                    $data['type'] = $n['type'];
                    if (!$data['amount'])
                        continue;
                    if (($data['type'] == 'transfer' || $data['type'] == 'credit') && ($data['account_id'] == $data['inaccount_id']))
                        continue;
                    $this->_insert($data);
                    $i++;
                }
            }
            if ($i > 0) {
                $info = "提交成功,成功录入{$i}条记录";
                $status = 'y';
            } else {
                $info = "提交失败,请重试";
                $status = 'n';
            }
            dialog_output($status, $info, $data);
        }
        render("mobile/bill/multi");
    }

    function _insert($data = array()) {
        $value['type'] = $data['type'];
        $value['occurtime'] = strtotime($data['occurtime']);
        $value['category_id'] = isset($data['category_id']) ? $data['category_id'] : 0;
        $value['account_id'] = $data['account_id'];
        $value['inaccount_id'] = isset($data['inaccount_id']) ? $data['inaccount_id'] : 0;
        $value['amount'] = $data['amount'];
        $value['memo'] = $data['memo'];
        $value['family'] = isset($data['notinfamily']) ? 0 : 1;
        $value['createtime'] = $data['modifytime'] = time();
        $value['user_id'] = $this->auth->user_id;
        $value['outstanding'] = $value['type'] == 'borrow' ? $value['amount'] : 0;
        if ($data['repeat'] == 1) {
            $taskvalue = $value;
            $taskvalue['title'] = $value['memo'] ? $value['memo'] : '未命名定时任务';
            $taskvalue['frequency'] = $this->input->post("repeatlist");
            $taskvalue['executes'] = 0;
            $taskvalue['maximums'] = 0;
            $taskvalue['starttime'] = time();
            $taskvalue['expiretime'] = 0;
            $taskvalue['state'] = 1;
            unset($taskvalue['outstanding'], $taskvalue['modifytime'], $taskvalue['occurtime']);
            $this->db->insert("{pre}task", $taskvalue);
        }
        $id = $this->db->insert("{pre}bill", $value);

        if ($value['inaccount_id'] && in_array($value['type'], array('transfer', 'credit'))) {
            $this->account->update_user_account($value['inaccount_id'], $value['amount'], "新增记账[{$value['memo']}]ID[{$id}],类型[{$value['type']}]");
        }
        $amount = $value['type'] == 'income' || (($value['type'] == 'borrow') && $value['category_id'] == 2) ? $value['amount'] : -$value['amount'];
        $this->account->update_user_account($value['account_id'], $amount, "新增记账[{$value['memo']}],ID[{$id}],类型[{$value['type']}],类别[{$value['category_id']}]");
        return true;
    }

    function del($id) {
        $code = -1;
        $content = '';
        $bill = $this->db->one("SELECT * FROM {pre}bill WHERE id='{$id}'");
        if ($bill) {
            if ($bill['user_id'] == $this->auth->user_id) {
                $this->db->query("DELETE FROM {pre}bill WHERE id='{$id}'");
                if ($bill['father_id'] > 0 && $bill['type'] == 'borrow') {
                    $this->db->query("UPDATE {pre}bill SET outstanding=outstanding+{$bill['amount']} WHERE id='{$bill['father_id']}'");
                }
                if ($bill['inaccount_id'] && in_array($bill['type'], array('transfer', 'credit'))) {
                    $this->account->update_user_account($bill['inaccount_id'], -$bill['amount'], "删除记账[{$bill['memo']}],ID[{$id}],类型[{$bill['type']}]");
                }
                $amount = $bill['type'] == 'income' || (($bill['type'] == 'borrow') && ($bill['category_id'] == 2 || $bill['category_id'] == 3)) ? -$bill['amount'] : $bill['amount'];
                $this->account->update_user_account($bill['account_id'], $amount, "删除记账[{$bill['memo']}],ID[{$id}],类型[{$bill['type']}],类别[{$bill['category_id']}]");
                $code = 0;
                $content = '操作成功';
            } else {
                $content = '不能进行越权操作!';
            }
        } else {
            $content = '记录未找到!';
        }
        json_output($code, $content);
    }

}